import { Middleware, MiddlewareContext } from '../../core/types';

export interface EncryptOptions {
  encryptRequest?: boolean;
  encryptResponse?: boolean;
  encrypt?: (data: any) => string;
  decrypt?: (data: string) => any;
}

export function encrypt(options: EncryptOptions = {}): Middleware {
  const {
    encryptRequest = false,
    encryptResponse = false,
    encrypt = (data) => btoa(JSON.stringify(data)),
    decrypt = (data) => JSON.parse(atob(data)),
  } = options;

  return async (ctx: MiddlewareContext, next) => {
    // Request encryption
    if (encryptRequest && ctx.request && ctx.config.data) {
      ctx.config.data = encrypt(ctx.config.data);
      ctx.config.headers = {
        ...ctx.config.headers,
        'Content-Type': 'text/plain',
      };
    }

    await next();

    // Response decryption
    if (
      encryptResponse &&
      ctx.response &&
      typeof ctx.response.data === 'string'
    ) {
      try {
        ctx.response.data = decrypt(ctx.response.data);
      } catch (error) {
        ctx.error = new Error('Failed to decrypt response') as any;
        throw ctx.error;
      }
    }
  };
}
